package org.ecloud.utils;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.Args;
import org.ecloud.common.exception.BaseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Lists;

public class HttpClientUtil {
	
	private HttpClientUtil(){}
	
	private static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);
	
    public static String doGet(String url, Header ... headers) {
        try {
            return Request.Get(url).setHeaders(headers).execute().returnContent().asString(Consts.UTF_8);
        } catch (IOException e) {
        	throw new BaseException(e);
        }
    }

    public static String doGet(String url, Map<String, String> paramMap, Header ... headers) {
        return doGet(url, null, null, null, paramMap, headers);
    }

    public static String doGet(String url, String hostName, Integer port, String schemeName, Map<String, String> paramMap, Header ... headers) {
        return executeGet(url, hostName, port, schemeName, paramMap, headers);
    }
    
    private static String executeGet(String url, String hostName, Integer port, String schemeName, Map<String, String> paramMap, Header ... headers) {
        Args.notNull(url, "url");
        logger.debug("execute get url =============> {}", url);
        
        url = buildGetParam(url, paramMap);
        Request request = Request.Get(url);
        request.setHeaders(headers);
        request = buildProxy(request, hostName, port, schemeName);
        try {
            return request.execute().returnContent().asString(Consts.UTF_8);
        } catch (IOException e) {
        	throw new BaseException(e);
        }
    }
    
    private static String buildGetParam(String url, Map<String, String> paramMap) {
        Args.notNull(url, "url");
        if(MapUtils.isNotEmpty(paramMap)) {
            List<NameValuePair> paramList = Lists.newArrayListWithCapacity(paramMap.size());
            for (String key : paramMap.keySet()) {
                paramList.add(new BasicNameValuePair(key, paramMap.get(key)));
            }
            //拼接参数
            url += "?" + URLEncodedUtils.format(paramList, Consts.UTF_8);
        }
        return url;
    }

    public static String doPost(String url, Header ... headers) {
        return doPost(url, (List<NameValuePair>)null, headers);
    }

    public static String doPost(String url, List<NameValuePair> nameValuePairs, Header ... headers) {
        return doPost(url, null, null, null, nameValuePairs, null, headers);
    }

    public static void doPost(String url, List<NameValuePair> nameValuePairs, File file, Header ... headers) {
        doPost(url, null, null, null, nameValuePairs, file, headers);
    }

    public static String doPost(String url, String hostName, Integer port, String schemeName, List<NameValuePair> nameValuePairs, File file, Header ... headers) {
        return executePost(url, hostName, port, schemeName, nameValuePairs, file, headers);
    }
    
    private static String executePost(String url, String hostName, Integer port, String schemeName, List<NameValuePair> nameValuePairs, File file, Header ... headers) {
        Args.notNull(url, "url");
        logger.debug("execute post url =============> {}", url);
        
        HttpEntity entity = buildPostParam(nameValuePairs, file);
        Request request = Request.Post(url);
        request.setHeaders(headers);
        request.body(entity);
        request = buildProxy(request, hostName, port, schemeName);
        try {
            return request.execute().returnContent().asString(Consts.UTF_8);
        } catch (IOException e) {
        	throw new BaseException(e);
        }
    }
    
    /**
     * 构建POST方法请求参数
     * @return
     */
    private static HttpEntity buildPostParam(List<NameValuePair> nameValuePairs, File file) {
        if(CollectionUtils.isEmpty(nameValuePairs) && null == file) {
            return null;
        }
        if(null != file) {
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            ContentBody contentBody = new FileBody(file);
            builder.addPart("file", contentBody).setCharset(Consts.UTF_8);
            
            if(CollectionUtils.isNotEmpty(nameValuePairs)){
	            for (NameValuePair nameValuePair : nameValuePairs) {
	                //设置ContentType为UTF-8,默认为text/plain; charset=ISO-8859-1,传递中文参数会乱码
	                builder.addTextBody(nameValuePair.getName(), 
	                		nameValuePair.getValue(), 
	                		ContentType.create("text/plain", Consts.UTF_8));
	            }
            }
            return builder.build();
        } else {
            try {
                return new UrlEncodedFormEntity(nameValuePairs);
            } catch (UnsupportedEncodingException e) {
            	throw new BaseException(e);
            }
        }
    }
    
//    public static void doPost(String url, List<NameValuePair> nameValuePairs, String originalFilename, InputStream stream) {
//        doPost(url, null, null, null, nameValuePairs, originalFilename, stream);
//    }
//
//    public static String doPost(String url, String hostName, Integer port, String schemeName, List<NameValuePair> nameValuePairs, String originalFilename, InputStream stream) {
//        return executePost(url, hostName, port, schemeName, nameValuePairs, originalFilename, stream);
//    }
//    
//    private static String executePost(String url, String hostName, Integer port, String schemeName, List<NameValuePair> nameValuePairs, String originalFilename, InputStream stream) {
//        Args.notNull(url, "url");
//        HttpEntity entity = buildPostParam(nameValuePairs, originalFilename, stream);
//        Request request = Request.Post(url).body(entity);
//        request = buildProxy(request, hostName, port, schemeName);
//        try {
//            return request.execute().returnContent().asString(Consts.UTF_8);
//        } catch (IOException e) {
//            LOGGER.error(e.getMessage(), e.toString());
//        }
//        return null;
//    }
//    
//    /**
//     * 构建POST方法请求参数
//     * @return
//     */
//    private static HttpEntity buildPostParam(List<NameValuePair> nameValuePairs, String originalFilename, InputStream stream) {
//        if(CollectionUtils.isEmpty(nameValuePairs) && null == stream) {
//            return null;
//        }
//        if(null != stream) {
//            MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
//            ContentBody contentBody = new InputStreamBody(stream, ContentType.MULTIPART_FORM_DATA, originalFilename);
//            builder.addPart("file", contentBody).setCharset(Consts.UTF_8);
//            if(CollectionUtils.isNotEmpty(nameValuePairs)){
//	            for (NameValuePair nameValuePair : nameValuePairs) {
//	                //设置ContentType为UTF-8,默认为text/plain; charset=ISO-8859-1,传递中文参数会乱码
//	                builder.addTextBody(nameValuePair.getName(), 
//	                		nameValuePair.getValue(), 
//	                		ContentType.create("text/plain", Consts.UTF_8));
//	            }
//            }
//            return builder.build();
//        } else {
//            try {
//                return new UrlEncodedFormEntity(nameValuePairs);
//            } catch (UnsupportedEncodingException e) {
//                LOGGER.error(e.getMessage(), e.toString());
//            }
//        }
//        return null;
//    }
//    
//    public static void doPost(String url, List<NameValuePair> nameValuePairs, String originalFilename, byte[] stream) {
//        doPost(url, null, null, null, nameValuePairs, originalFilename, stream);
//    }
//
//    public static String doPost(String url, String hostName, Integer port, String schemeName, List<NameValuePair> nameValuePairs, String originalFilename, byte[] stream) {
//        return executePost(url, hostName, port, schemeName, nameValuePairs, originalFilename, stream);
//    }
//    
//    private static String executePost(String url, String hostName, Integer port, String schemeName, List<NameValuePair> nameValuePairs, String originalFilename, byte[] stream) {
//        Args.notNull(url, "url");
//        HttpEntity entity = buildPostParam(nameValuePairs, originalFilename, stream);
//        Request request = Request.Post(url).body(entity);
//        request = buildProxy(request, hostName, port, schemeName);
//        try {
//            return request.execute().returnContent().asString(Consts.UTF_8);
//        } catch (IOException e) {
//            LOGGER.error(e.getMessage(), e.toString());
//        }
//        return null;
//    }
//    
//    /**
//     * 构建POST方法请求参数
//     * @return
//     */
//    private static HttpEntity buildPostParam(List<NameValuePair> nameValuePairs, String originalFilename, byte[] stream) {
//        if(CollectionUtils.isEmpty(nameValuePairs) && null == stream) {
//            return null;
//        }
//        if(null != stream) {
//            MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
//            ContentBody contentBody = new ByteArrayBody(stream, ContentType.MULTIPART_FORM_DATA, originalFilename);
//            builder.addPart("file", contentBody).setCharset(Consts.UTF_8);
//            if(CollectionUtils.isNotEmpty(nameValuePairs)){
//	            for (NameValuePair nameValuePair : nameValuePairs) {
//	                //设置ContentType为UTF-8,默认为text/plain; charset=ISO-8859-1,传递中文参数会乱码
//	                builder.addTextBody(nameValuePair.getName(), 
//	                		nameValuePair.getValue(), 
//	                		ContentType.create("text/plain", Consts.UTF_8));
//	            }
//            }
//            return builder.build();
//        } else {
//            try {
//                return new UrlEncodedFormEntity(nameValuePairs);
//            } catch (UnsupportedEncodingException e) {
//                LOGGER.error(e.getMessage(), e.toString());
//            }
//        }
//        return null;
//    }

    /**
     * 设置代理，使用代理机代替自己去访问，解决自己IP被禁的问题
     * @param request
     * @param hostName
     * @param port
     * @param schemeName
     * @return
     */
    private static Request buildProxy(Request request, String hostName, Integer port, String schemeName) {
        if(StringUtil.isNotEmpty(hostName) && port != null) {
            //设置代理
            if (StringUtil.isEmpty(schemeName)) {
                schemeName = HttpHost.DEFAULT_SCHEME_NAME;
            }
            request.viaProxy(new HttpHost(hostName, port, schemeName));
        }
        return request;
    }

}
